#include "LoopController.h"

#include <cstring>
#include <iostream>

#include "ConfigManager.h"
#include "MachineDependenceConst.h"

LoopController::LoopController(DummyChannel& channel, const ExtendDeviceType& deviceType, const std::string& deviceActknowlege, const LoopSize_t& startIndex, const LoopSize_t& portCount) : AcDetector(channel, deviceType, deviceActknowlege
, startIndex, portCount){

}


LoopController::~LoopController() {
    free(mloopStatusArray);
    mloopStatusArray = nullptr;
    free(mbackupLoopStatusArray);
    mbackupLoopStatusArray = nullptr;
}


int LoopController::initLoopGroupInfo(LoopGroupInfos& loopGroups) {
    // 当前设备的剩余回路数量
    int loopDeviceNum = this->mportCount;
    LoopGroupInfo* loopGroupTemp;
    // 在当前设备中的序号
    int currentNumber = 0;
    while (loopDeviceNum > MDConst::DEFAULT_INTERNAL_LOOP_COUNT) {
        loopGroupTemp = new LoopGroupInfo(this->mdeviceType.name, 0, this->mchannel.mchannel, MDConst::DEFAULT_INTERNAL_LOOP_COUNT, currentNumber);
        loopGroups.push_back(*loopGroupTemp);
        loopDeviceNum -= MDConst::DEFAULT_INTERNAL_LOOP_COUNT;
        currentNumber += MDConst::DEFAULT_INTERNAL_LOOP_COUNT;
    }
    loopGroupTemp = new LoopGroupInfo(this->mdeviceType.name, 0, this->mchannel.mchannel, loopDeviceNum, currentNumber);
    loopGroups.push_back(*loopGroupTemp);

    return 1;
}



void LoopController::allocStatusMemory() {
    const size_t size = sizeof (LoopStatus) * mportCount;
    mloopStatusArray = reinterpret_cast<LoopStatus*> (malloc(size));
    mbackupLoopStatusArray = reinterpret_cast<LoopStatus*> (malloc(size));

    std::memset(mloopStatusArray, LoopStatus::AUTO_OFF, size);
    std::memset(mbackupLoopStatusArray, LoopStatus::NO_BACKUP_STATUS, size);
}



   bool LoopController::initialize() noexcept {
        LoopSize_t tempSize = mportCount;
        AcDetector::initialize();

        LoopSize_t* psize = const_cast<LoopSize_t*>(&mportCount);
        *psize = tempSize;//restore

        mloopPhases.resize(mportCount, 'A');
        buildCommandAndSavePhase();

        updateLoopControllerConfig(ConfigManagerSingleton::instance().getExtendDeviceConfig().loopControllerInfo);

        allocStatusMemory();

        return true;
   }


void LoopController::changeAllChannelStatusFunc(const LoopStatus* command, const LoopSize_t& length) {
    //             <CIRCUIT_ON/OFF_DATA_000000000000_00500>
    std::string mcommandBuilder = "<CIRCUIT_ON/OFF_DATA_";
   // buildCommandString(command.first.get(), command.second, mcommandBuilder);
    mcommandBuilder.append(reinterpret_cast <const char*>(command), length);
    mcommandBuilder;
    char buffer[8];
    snprintf(buffer, sizeof (buffer), "_%05d>", mloopControllerConfig.switchInterval);
    mcommandBuilder.append(buffer, sizeof (buffer) - 1);
    std::string result;

    mchannel.sendStringReturnString(mcommandBuilder, result);
//    if (mcommandBuilder != result){
//        throw BUILD_EXCEPTION_MESSAGE(FirmwareError::LOOP_SWITCH_FAILED, result);
//    }
}



void LoopController::changeSingleChannelStatusFunc(const int& loopIndex, const LoopStatus& status) {
    std::string mcommandBuilder = "<CIRCUIT_ON/OFF_ONE_";
    mcommandBuilder += BINARY_TO_CHAR(loopIndex);
    mcommandBuilder += '_';
    mcommandBuilder += status;
    mcommandBuilder +=  '>';

    std::string result;
    mchannel.sendStringReturnString(mcommandBuilder, result);
}


